package cn.tedu.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
//反射Student类里的所有信息
public class Test2_Student {
    public static void main(String[] args) throws Exception {
        //1,获取Student类的Class对象
        Class s = Student.class;
        method(s);//解析构造方法
//        method2(s);//解析 成员变量
//        method3(s);//解析 成员方法
//        method4(s);//用反射创建对象
//        method5(s);//用反射设置变量值
//        method6(s);//用反射 执行方法
    }
    //用反射  执行方法
    public static void method6(Class s) throws Exception{
        //获取指定的方法 public void test(int a)
        Method m = s.getMethod("test",int.class);
        //执行方法
        //invoke(m,n)---m是对象---n时要给方法传入的参数
        Object o = s.newInstance();
        m.invoke(o,50);//执行方法
    }
    //用反射  设置变量值
    public static void method5(Class s) throws Exception {
        Field f = s.getField("name");
        Object o = s.newInstance();
        //set(m,n)--m是对象---n是想要设置的值
        f.set(o,"jack");//设置值
        f.get(o);//获取值
        System.out.println(f.get(o));
    }
    //用反射  创建对象
    public static void method4(Class s) throws Exception {
        //用反射new---自动调用了无参构造
        Object o = s.newInstance();
        System.out.println(o);
        if(o instanceof Student){
            Student s2 = (Student)o;//向下转型，目的是使用子类的特有功能
            s2.show();//使用了Student类里功能
        }
    }
    //用反射 获取方法
    public static void method3(Class s) throws Exception {
        //获取所有方法
        Method[] ms = s.getMethods();
        //遍历数组
        for(Method m:ms){
            System.out.println(m.getName());
            Class[] c = m.getParameterTypes();//获取方法名
            System.out.println(Arrays.toString(c));//获取参数类型
        }
        //TODO 1  获取特定的 方法 public void test(int a)
        Method m = s.getMethod("test",int.class);
        System.out.println(m.getName());
    }

    //解析 Student.class 文件中的  成员变量
    public static void method2(Class s) throws Exception{
        //获取所有成员变量们
        Field[] fs = s.getFields();
        //遍历，得到每个成员变量f
        for(Field f:fs){
            System.out.println(f.getName());//获取变量名
            System.out.println(f.getType().getName());//获取变量类型
        }
        //根据属性名来获取属性
        Field f = s.getField("age");
        //获取属性类型
        System.out.println(f.getType().getName());
    }

    //解析Student.class文件中的构造方法
    //getConstrectors() getConstructor()----获取公开的
    public static void method(Class s) throws Exception {
        //获取 所有的构造方法 存入Constructor[]
        Constructor[] cs = s.getConstructors();
//        System.out.println(cs);
        //遍历数组,得到每个构造方法c
        for (Constructor c : cs) {
            //获取构造方法的 名称
            System.out.println(c.getName());
            //TODO 解析构造方法的 参数的类型
            Class[] cc = c.getParameterTypes();
            System.out.println(Arrays.toString(cc));
        }
//        System.out.println(Arrays.toString(cc));
        //TODO 获取指定的构造方法 --public Student(int age)
        //getConstructor()的参数是 构造方法的参数类型 的Class对象
        Constructor con = s.getConstructor(int.class);
        System.out.println( con.getName()+"~~~" );
    }
}
